package com.tamakloe.guestbook;

import java.util.Date;
import java.util.logging.Logger;
import javax.jdo.PersistenceManager;
import javax.servlet.http.HttpServletRequest;
import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;



public class GuestForm extends Form  {
	   // Constants ----------------------------------------------------------------------------------
	private static final Logger log = Logger.getLogger(GuestForm.class.getName());
    private static final String FIELD_USERNAME = "userName";
    private static final String FIELD_CONTENT = "content";
    private static final String FIELD_EMAIL = "userEmail";
    private static final String FIELD_RESULT = "result";
    private static final String FIELD_CHALLENGE = "recaptcha_challenge_field";
    private static final String FIELD_RESPONSE = "recaptcha_response_field";
    private static final String PRIVATE_KEY = "6LcBgwYAAAAAAPaui3JoHpAq95vcN09YxQEeWrth";


    // Variables ----------------------------------------------------------------------------------

    private Greeting greeting;

    // Constructors -------------------------------------------------------------------------------

    /**
     * Construct a Greeting Form associated with the given greeting.
     * @param greeting The greeting to be associated with the Greeting Form.
     */
    public GuestForm(Greeting greeting) {
        this.greeting = greeting;
    }
    
    // Form actions -------------------------------------------------------------------------------

    /**
     * Returns the greeting based on the given request. It will gather all form fields,
     * process and validate the fields and save the created greeting using the greeting associated with
     * this form.
     * @param request The request to register an User for.
     * @return The registered User based on the given request.
     */
    public Greeting registerGreeting(HttpServletRequest request) {
        greeting = new Greeting();

        try {
            processUsername(request, greeting);
            processContent(request, greeting);
            processEmail(request, greeting);
            processCaptcha(request, greeting);
            Date date = new Date();
            greeting.setDate(date);

            if (isSuccess()) {
                PersistenceManager pm = PMF.get().getPersistenceManager();
                try  {
                	pm.makePersistent(greeting);
                }finally {
                	pm.close();
                } 
                setMessage(FIELD_RESULT, "Message Posted!");
            }
        } catch (Exception e) {
            setError(FIELD_RESULT, "Message post failed due to database error."
                + " Please try again later. Detail message: " + e.getMessage());
            e.printStackTrace();
            log.warning(FIELD_RESULT + " " + "Message post failed due to database error."
                    + " Please try again later. Detail message: " + e.getMessage());
        }

        return greeting;
    }

    private void processCaptcha(HttpServletRequest request, Greeting greeting) {
    	  String challenge = FormUtil.getFieldValue(request, FIELD_CHALLENGE);
    	  String response  = FormUtil.getFieldValue(request, FIELD_RESPONSE);
    	  String remoteIp  = request.getRemoteAddr();
    	  /*
    	  RecaptchaResponse reCaptchaResp = new RecaptchaResponse(false, "");
    	  reCaptchaResp = reCaptchaResp.submit(challenge, response, PRIVATE_KEY, remoteIp);
    	  if (!reCaptchaResp.getIsValid()){
    		  setError(FIELD_RESPONSE, reCaptchaResp.getErrorCode());
    	  }
    	  */
    	  ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
    	    reCaptcha.setPrivateKey(PRIVATE_KEY);
    	    
    	    ReCaptchaResponse reCaptchaResponse =
    	        reCaptcha.checkAnswer(remoteIp, challenge, response);
    	    
    	    if (!reCaptchaResponse.isValid()) {
    	        setError(FIELD_RESPONSE, "Please try again." + reCaptchaResponse.getErrorMessage());
    	        log.warning(FIELD_RESPONSE + " " + "Please try again." + reCaptchaResponse.getErrorMessage());
    	    } 	
	}

	// Field processors ---------------------------------------------------------------------------

    /**
     * Process and validate the username which is to be associated with the given User.
     * If the username is null or if it is changed in the given user, then it will be validated.
     * The new username will be set in the given user regardless of the outcome of the validation.
     * @param request The request to get the username from.
     * @param user The User to be associated with the username.
     * @throws DAOException If something fails at DAO level.
     */
    public void processUsername(HttpServletRequest request, Greeting greeting)  {
        String username = FormUtil.getFieldValue(request, FIELD_USERNAME);

        if (username == null || FormUtil.isChanged(greeting.getUserName(), username)) {
            try {
                validateUsername(username);
            } catch (ValidatorException e) {
                setError(FIELD_USERNAME, e.getMessage());
                log.warning(FIELD_USERNAME + " " +  e.getMessage());
            }
            greeting.setUserName(username);
        }
    }

    /**
     * Process and validate the passwords which is to be associated with the given User.
     * The passwords will be validated regardless of the current password of the given user.
     * The password will be set in the given user only if validation succeeds.
     * @param request The request to get the passwords from.
     * @param user The User to be associated with the passwords.
     */
    public void processContent(HttpServletRequest request, Greeting greeting) {
        String content = FormUtil.getFieldValue(request, FIELD_CONTENT);
        if (content == null || FormUtil.isChanged(greeting.getContent(), content)) {
	        try {
	        	validateContent(content);
	            
	        } catch (ValidatorException e) {
	            setError(FIELD_CONTENT, e.getMessage());
	            log.warning(FIELD_CONTENT + " " + e.getMessage());
	        }
	        greeting.setContent(content);
        }
    }

    public void processEmail(HttpServletRequest request, Greeting greeting) {
        String email = FormUtil.getFieldValue(request, FIELD_EMAIL);

        if (email == null ||FormUtil.isChanged(greeting.getUserEmail(), email)) {
            try {
                validateEmail(email);
            } catch (ValidatorException e) {
                setError(FIELD_EMAIL, e.getMessage());
                log.warning(FIELD_EMAIL + " " + e.getMessage());
            }
            greeting.setUserEmail(email);
        }
    }


    // Field validators ---------------------------------------------------------------------------

    /**
     * Validate the given username. It will check if it is not null, is at least 3 characters long 
     * and is not already in use according to the User DAO associated with this form.
     * @param username The username to be validated.
     * @throws ValidatorException If the username is invalid.
     * @throws DAOException If something fails at DAO level.
     */
    public void validateUsername(String username) throws ValidatorException {
        if (username != null) {
            if (username.length() < 3) {
                throw new ValidatorException("Username should be at least 3 characters long.");
            } 
        } else {
            throw new ValidatorException("Please enter username.");
        }
    }

    public void validateContent(String content) throws ValidatorException {
        if (content != null) {
            if (content.length() < 3) {
                throw new ValidatorException("message should be at least 3 characters long.");
            } 
        } else {
            throw new ValidatorException("Please enter message.");
        }
    }

    public void validateEmail(String email) throws ValidatorException {
        if (email == null || !FormUtil.isEmail(email)) {
            	throw new ValidatorException("Please enter valid email address.");
        }
    }



}
